using System;
using AltNetHispano.Vale.Tests.Example;
using NUnit.Framework;
using SharpTestsEx;

namespace AltNetHispano.Vale.Tests
{
	[TestFixture]
	public class ConstraintsInPropertyTest
	{
		[Test]
		public void CanValidateAConstraintForName()
		{
			var validator = new Validator();
			validator.Register<Person>(p => validator.StringIsRequired("First name", p.Name), p => p.Name);
			validator.GetInvalidMessages(new Person {Name = null}, p => p.Name)
					.Should().Contain("First name is required.");
		}

		[Test]
		public void CanValidatePropertyWithoutConstraint()
		{
			var validator = new Validator();
			
			validator.Register<Person>(p => validator.StringIsRequired("First name", p.Name), p => p.Name);

			validator.GetInvalidMessages(new Person { Name = null }, p => p.Birthday);
		}

		[Test]
		public void CanRegisterConstraintForPropertyAndValidateWholeEntity()
		{
			var validator = new Validator();
			
			validator.Register<Person>(p => validator.StringIsRequired("First name", p.Name), p => p.Name);

			validator.GetInvalidMessages(new Person { Name = null })
					.Should().Contain("First name is required.");
		}

		[Test]
		public void CanValidatePropertyWithPropertyName()
		{
			var validator = new Validator();

			validator.Register<Person>(p => validator.StringIsRequired("First name", p.Name), p => p.Name);

			validator.GetInvalidMessages(new Person { Name = null }, "Name")
					.Should().Contain("First name is required.");
		}

		[Test]
		public void ValidatePropertyWithPropertyNameWithoutAConstraintReturnEmpty()
		{
			var validator = new Validator();

			validator.GetInvalidMessages(new Person { Name = null }, "Name")
					.Should().Be.Empty();
		}

		[Test]
		public void ValidatePropertyWithWrongPropertyNameThrowArgumentException()
		{
			var validator = new Validator();

			const string wrongPropertyName = "Name123d";

			validator.Executing(v => v.GetInvalidMessages(new Person {Name = null}, wrongPropertyName))
				.Throws<ArgumentException>()
				.And.Exception.Message.Should().Be.EqualTo(string.Format("{0} is not a property", wrongPropertyName));

					
		}
	}
}